package cn.com.dhcc.turbo.service.registry.sync;

import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import cn.com.dhcc.app.core.exception.NiceException;
import cn.com.dhcc.app.core.exception.ServiceException;
import cn.com.dhcc.app.core.handler.remotehandler.socket.ICallBack;
import cn.com.dhcc.app.core.handler.remotehandler.socket.ISendDataClient;
import cn.com.dhcc.app.core.service.Log;
import cn.com.dhcc.app.core.service.Log.LOGTYPE;
import cn.com.dhcc.app.core.tag.CommonStaticCode.SUCCESSFAIL;
import cn.com.dhcc.app.core.util.NetUtil;
import cn.com.dhcc.app.pub.core.consts.AppIocBean;
import cn.com.dhcc.app.pub.core.tag.AppTagEl;
import cn.com.dhcc.turbo.entity.registry.NodeInfo;
import cn.com.dhcc.turbo.entity.registry.NodePipeline;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo.SyncOperType;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo.SyncStatus;
import cn.com.dhcc.turbo.entity.registry.SynchronizeInfo.SyncType;
import cn.com.dhcc.turbo.service.exch.DistributedNodeInfoService;
import cn.com.dhcc.turbo.service.registry.NodeInfoService;
import cn.com.dhcc.turbo.service.registry.vo.NodeRegistSyncData;
/**
 * RMI 同步方式
 * @author qiao
 * @2014-8-26 @下午2:44:20
 */
@Service(AppIocBean.SYNC_SENDER_RMI_IMPL)
public class SyncSenderRmiImpl implements ISyncSender {

	@Autowired
	@Qualifier(AppIocBean.HTTP_SEND_DATA_CLIENT)
	ISendDataClient socketClient;
	@Autowired
	SynchronizeHandler synchronizeHandler;
	@Autowired
	NodeInfoService nodeInfoService;
	@Autowired
	DistributedNodeInfoService distributedNodeInfoService;
	
	//private String ip;
	//private int port; 
	
	@SuppressWarnings("deprecation")
	private static Logger logger = Log.getExistLogger(LOGTYPE.SYNC);
	/**
	 * syncUrl --> ip:port
	 */
	
	public void analyseSyncUrl(String syncUrl) {
		/*String[] ip_port = syncUrl.split(":");
		ip = ip_port[0];
		port = Integer.parseInt(ip_port[1]);*/
	}

	/**
	 * @throws Exception 
	 * 
	 */
	@Override
	public SyncCallBack sendData( String syncUrl,final SynchronizeInfo synchronizeInfo) throws Exception {
		final SyncCallBack backMsg = new SyncCallBack();
		/*String resp =  distributedNodeInfoService.getRmi(synchronizeInfo.getToNodeInfo());
        if (resp==null || "".equals(resp) ||  resp.split(":").length<2) {
        	backMsg.setResult(SUCCESSFAIL.FAIL);
        	backMsg.setMsg("获取RMI地址的响应无法解析resp值无效:["+resp+"]");
        	return backMsg;
		}*/
		/*String[] ip_port = resp.split(":");
		String ip = ip_port[0];
		int port = Integer.parseInt(ip_port[1]);*/
		final String dataType = synchronizeInfo.getDataType();
		logger.info("开始同步["+AppTagEl.getNameFromCode(SyncType.class, synchronizeInfo.getDataType())
				   +"]信息给节点["+synchronizeInfo.getToNodeInfo().getNodeName()+"]," +
				   		"数据源节点["+synchronizeInfo.getSrcNodeInfo().getNodeName()+"],接收地址：["+syncUrl+"]");
		//发送
		socketClient.sendData(syncUrl, 0, synchronizeInfo, new ICallBack() {
			@Override
			public void recevieCallBackData(Object callBackData) {
				SyncCallBack callBack = (SyncCallBack)callBackData;
				SUCCESSFAIL status = callBack.getResult();
				//失败
				if(status.getStatus().equals(SUCCESSFAIL.FAIL.getStatus())){
					synchronizeInfo.setStatus(SyncStatus.FAIL.getCode());
					synchronizeInfo.setRemark(callBack.getMsg());
					backMsg.setResult(SUCCESSFAIL.FAIL);
					backMsg.setMsg(callBack.getMsg());
					if(SyncType.NODE_REGIST.getCode().equalsIgnoreCase(dataType)){//处理节点注册的返回
						backMsg.setMsg(callBack.getMsg());
					}else if(SyncType.CREATE_REL.getCode().equalsIgnoreCase(dataType)){//建立交换关系
						backMsg.setMsg(callBack.getMsg());
					}else if(SyncType.REL_PIPE_LINE.getCode().equalsIgnoreCase(dataType)){
						backMsg.setMsg(callBack.getMsg());
					}else{
						if(synchronizeInfo.isWhenErrorRepeat()){//是否重发
							try {
								synchronizeHandler.insertOrUpdateSynchronizeInfo(synchronizeInfo);
							} catch (ServiceException e) {
								//这一步不能失败
								logger.error(e);
							}
						}
					}
				}else{
					logger.info("同步["+AppTagEl.getNameFromCode(SyncType.class, synchronizeInfo.getDataType())
							   +"]信息给节点["+synchronizeInfo.getToNodeInfo().getNodeName()+"]成功");
					
					backMsg.setResult(SUCCESSFAIL.SUCCESS);
					synchronizeInfo.setStatus(SyncStatus.SUCCESS.getCode());
					
					if(SyncType.NODE_REGIST.getCode().equalsIgnoreCase(dataType)){//处理节点注册的返回
						//接收注册节点返回来的通道信息
						NodeRegistSyncData nodeRegistSyncData = (NodeRegistSyncData) callBack.getNodeRegistSyncData();
						List<NodePipeline> remoteNodePipeLines = nodeRegistSyncData.getAllPipeInfos();
						synchronizeHandler.setNodesPipeLinesToUnLocalFlag(remoteNodePipeLines, null);
						NodeInfo registNode = nodeRegistSyncData.getRegistNode();
						try {
							nodeInfoService.insertOrUpdate(nodeRegistSyncData.getRegistNode());
							synchronizeHandler.insertOrUpdateSyncPipeLineInfo(remoteNodePipeLines);
							//开始全网同步，已注册的节点基本信息和节点的通道信息
							synchronizeHandler.syncToAllNodes(SyncType.NODE_INFO, false, registNode,registNode, nodeRegistSyncData.getRegistNode(), SyncOperType.INSERT,true);
							//synchronizeHandler.syncToAllNodes(SyncType.PILE_LINE_LIST, false, registNode,registNode,  remoteNodePipeLines, SyncOperType.INSERT,true);
						} catch (ServiceException e) {
							backMsg.setResult(SUCCESSFAIL.FAIL);
							backMsg.setMsg("节点注册失败");
						}catch (NiceException e) {
							//节点同步失败
						}
					}else if(SyncType.CREATE_REL.getCode().equalsIgnoreCase(dataType)){//建立交换关系
						backMsg.setMsg(callBack.getMsg());
						backMsg.setStatus(callBack.getStatus());
					}else if(SyncType.REL_PIPE_LINE.getCode().equalsIgnoreCase(dataType)){
						backMsg.setMsg(callBack.getMsg());
						backMsg.setNodePipeline(callBack.getNodePipeline());
					}else if(SyncType.TEST_CONNECT.getCode().equalsIgnoreCase(dataType)){
						
					}else{
						if(synchronizeInfo.isWhenErrorRepeat()){//是否重发,只有重发的才入库
							try {
								synchronizeHandler.insertOrUpdateSynchronizeInfo(synchronizeInfo);
							} catch (ServiceException e) {
								//这一步不能失败
								logger.error(e);
							}
						}
					}
				}
			}
			@Override
			public void onException(Throwable cause){
				synchronizeInfo.setStatus(SyncStatus.FAIL.getCode());
				backMsg.setResult(SUCCESSFAIL.FAIL);
				synchronizeInfo.setRemark(cause.getMessage());
				if(SyncType.NODE_REGIST.getCode().equalsIgnoreCase(dataType)){//处理节点注册的返回
					backMsg.setMsg("节点注册失败,"+cause.getMessage());
				}else{
					try {
						synchronizeHandler.insertOrUpdateSynchronizeInfo(synchronizeInfo);
					} catch (ServiceException e) {
						//这一步不能失败
					}
				}
			}
		});
		return backMsg;
	}
	public boolean syncUrlIsValid(String syncUrl){
		
	/*	
	 * 使用rmi去测试连接，会阻塞很长时间
	 * try {
			SynchronizeInfo synchronizeInfo = new SynchronizeInfo();
			synchronizeInfo.setFromNodeInfo(nodeInfoService.getLocalNode());
			synchronizeInfo.setDataType(SyncType.TEST_CONNECT.getCode());
			SyncCallBack callBack = sendData(syncUrl,synchronizeInfo);
			if(callBack!=null&&callBack.getResult()==SUCCESSFAIL.SUCCESS){
				return true;
			}
		} catch (Exception e) {
			logger.error(e);
		}
		return false;*/
		if(!StringUtils.hasText(syncUrl)){
			return false;
		}
		/*try {
			boolean exist = nodeInfoService.isSyncUrlExist(syncUrl);
			if(exist)return false;
		} catch (ServiceException e) {
			return false;
		}*/
		syncUrl = syncUrl.trim();
		String[] ip_port = syncUrl.split(":");
		String ip = ip_port[0];
		int port = Integer.parseInt(ip_port[1]);
		//不能和当前节点相同
		return NetUtil.canConnect(ip, port);
	}
	
}
